/**
 * Copyright [2019] [LiBo/Alex of copyright liboware@gmail.com ]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.dess.base.scanner;

import org.eclipse.osgi.container.Module;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Set;

/**
 * @project-name:dess
 * @package-name:com.hyts.dess.base.scanner
 * @author:LiBo/Alex
 * @create-date:2020-06-13 16:28
 * @copyright:libo-alex4java
 * @email:liboware@gmail.com
 * @description:
 * 1）获得某个类型的所有子类型
 * 2）获得标记了某个注解的所有类型／成员变量，支持注解参数匹配。
 * 3）使用正则表达式获得所有匹配的资源文件
 * 4）获得所有特定签名（包括参数，参数注解，返回值）的方法
 */
public class ClassScanner {


    @SuppressWarnings("all")
    public static Set<Class<?>> getClassesByAnnotation(Class annotationClass,Class superClass,String... packages){
        Reflections reflections = new Reflections(packages);
        Set<Class<?>> subTypes = reflections.getSubTypesOf(superClass);
       return  reflections.getTypesAnnotatedWith(annotationClass);
    }


    public static void main(String[] args){
       Reflections reflections = new Reflections("com.hyts");
//        //or using ConfigurationBuilder
//        new Reflections(new ConfigurationBuilder()
//                .setUrls(ClasspathHelper.forPackage("my.project.prefix"))
//                .setScanners(new SubTypesScanner(),
//                        new TypeAnnotationsScanner().filterResultsBy(optionalFilter),),
//                 .filterInputsBy(new FilterBuilder().includePackage("my.project.prefix"))
//        );
        //SubTypesScanner
//        Set<Class<? extends Module>> modules =
//                reflections.getSubTypesOf(com.google.inject.Module.class);
//        //TypeAnnotationsScanner
//        Set<Class<?>> singletons =
//                reflections.getTypesAnnotatedWith(javax.inject.Singleton.class);
//        //ResourcesScanner
//        Set<String> properties =
//                reflections.getResources(Pattern.compile(".*\\.properties"));
//        //MethodAnnotationsScanner
//        Set<Method> resources =
//                reflections.getMethodsAnnotatedWith(javax.ws.rs.Path.class);
//        Set<Constructor> injectables =
//                reflections.getConstructorsAnnotatedWith(javax.inject.Inject.class);
//        //FieldAnnotationsScanner
//        Set<Field> ids =
//                reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
//        //MethodParameterScanner
//        Set<Method> someMethods =
//                reflections.getMethodsMatchParams(long.class, int.class);
//        Set<Method> voidMethods =
//                reflections.getMethodsReturn(void.class);
//        Set<Method> pathParamMethods =
//                reflections.getMethodsWithAnyParamAnnotated(PathParam.class);
//        //MethodParameterNamesScanner
//        List<String> parameterNames =
//                reflections.getMethodParamNames(Method.class)
//        //MemberUsageScanner
//        Set<Member> usages =
//                reflections.getMethodUsages(Method.class)
        Set<Method> someMethods = reflections.getMethodsMatchParams(long.class, int.class);
        System.out.println(someMethods);
    }




}
